/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			cmdargs.cc
  \date			Aug 2012
  \author		TNick

  \brief		Contains the implementation of CmdArgs class


*//*


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<cpg/cpg.h>

#include	<QString>
#include	<QChar>
#include	<QDir>

#include	<2D/p2d.h>
#include	<usermsg.h>
#include	<version3d.h>

#include	<cpg/cpglibrary.h>
#include	<cpg/file-formats/formatmanager.h>
#include	<cpg/file-formats/idrawfile.h>
#include	<cpg/plug-ins/plginman.h>
#include	<cpg/plug-ins/plugin.h>
#include	<cpg/logic/cpgdoc.h>
#include	<cpg/logic/pgspace.h>

#include	"pgcmdargs.h"

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  DEFINITIONS    --------------------------------------------------------- */

using namespace cpg;
using namespace cpg::PlugIns;

/*  DEFINITIONS    ========================================================= */
//
//
//
//
/*  DATA    ---------------------------------------------------------------- */

/*  DATA    ================================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/* ------------------------------------------------------------------------- */
CmdArgs::CmdArgs	( const QString & s_cmd, const QString & s_args )
	: BBlocks::CmdArgs( s_cmd, s_args )
{
	/* stub */
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
CmdArgs::~CmdArgs	( void )
{
	/* stub */
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
PgSpace *			CmdArgs::getSpace				(
		CmdArgs * inst, CpgDoc * doc, BBlocks::UserMsg & um, PgSpace * default_s  )
{

	if ( inst == NULL )
		return default_s;
	if ( inst->argumentsCount() == 0 )
		return default_s;

	bool			b;
	PgSpace *		spc;
	QString			s_arg = inst->argument( 0 );
	int				i = s_arg.toInt( &b );
	if ( b )
	{
		if ( ( i < 0 ) || ( i >= doc->spaceCount() ) )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The document [%1] - %2 contains %3 spaces.\n"
						"The index %4 is out of bounds.\n" )
					.arg( doc->id() )
					.arg( doc->documentName() )
					.arg( doc->spaceCount() )
					.arg( i )
					);
			spc = NULL;
		}
		else
		{
			spc = doc->space( i );
		}
	}
	else
	{
		spc = doc->spaceByName( s_arg );
		if ( spc == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The document [%1] - %2 does not contain a\n"
						"space named %3.\n")
					.arg( doc->id() )
					.arg( doc->documentName() )
					.arg( s_arg )
					.arg( i )
					);
		}
	}
	inst->plain_args_.removeAt( 0 );

	return spc;

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
CmdArgs::DataSrc			CmdArgs::getXY			(
		P2D & out, int i, BBlocks::UserMsg & um ) const
{
	bool	b;
	QString s_1;
	QString s_2;
	CmdArgs::DataSrc	ds = DS_ERROR;

	for ( ;; )
	{
		if ( named_args_.contains( "X" ) && named_args_.contains( "Y" ) )
		{
			s_1 = named_args_.value( "X" );
			s_2 = named_args_.value( "Y" );
			ds = NAMED_ARGS;
		}
		else if ( i + 2 <= plain_args_.count() )
		{
			s_1 = plain_args_.at( i + 0 );
			s_2 = plain_args_.at( i + 1 );
			ds = UNNAMED_ARGS;
		}
		else
		{
			break;
		}
		out.x_ = s_1.toDouble( &b );
		if ( !b ) break;
		out.y_ = s_2.toDouble( &b );
		if ( !b ) break;

		um.add( BBlocks::UserMsgMgr::MSG_INFO,
				QObject::tr( "%1, %2" )
				.arg( out.x_)
				.arg( out.y_ )
				);

		return ds;
	}
	um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
				"The input was not understood!"
				)
			);
	return DS_ERROR;

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
CpgDoc *					CmdArgs::getNamedDoc		( BBlocks::UserMsg & um )
{
	CpgDoc *	new_val;
	QString	s_arg;
	bool	b;

	/* named argument to indicate the document */
	if ( extractNamed( "DOC", s_arg ) )
	{
		int id = s_arg.toInt( &b );
		if ( ( id < 0 ) || ( b == false ) )
		{
			s_arg = QDir().absoluteFilePath( s_arg );
			new_val = CpgLibrary::docByFile( s_arg );
			if ( new_val == NULL )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The file that was provided:\n"
							"%1\n"
							"was not found to be associated with any document.\n"
							"Use the List command to get a list of valid id's.\n"
							)
						.arg( s_arg )
						);
				return NULL;
			}
		}
		else
		{
			new_val = CpgLibrary::docById( id );
			if ( new_val == NULL )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The argument that was provided - %1\n"
							"is numeric but is not a valid id. Use the\n"
							"List command to get a list of valid id's.\n"
							)
						.arg( id )
						);
				return NULL;
			}
		}

	}
	else
	{
		new_val = CpgLibrary::crtDoc();
		if ( new_val == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"There is no active document!\n" )
					);
			return NULL;
		}
	}
	return new_val;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool					CmdArgs::getNamedSpace		(
		BBlocks::UserMsg & um, CpgDoc * doc, PgSpace ** space )
{
	Q_ASSERT( doc != NULL );
	Q_ASSERT( space != NULL );
	PgSpace *	new_val = NULL;
	QString		s_arg;
	bool		b;

	/* named argument to indicate the document */
	if ( extractNamed( "SPC", s_arg ) )
	{
		int id = s_arg.toInt( &b );
		if ( ( id < 0 ) || ( b == false ) )
		{
			new_val = doc->spaceByName( s_arg );
			if ( new_val == NULL )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The space name that was provided:\n"
							"%1\n"
							"was not found inside document [%2] - %3.\n"
							)
						.arg( s_arg )
						.arg( doc->id() )
						.arg( doc->documentName() )
						);
			}
		}
		else
		{
			new_val = doc->space( id );
			if ( new_val == NULL )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The argument that was provided - %1\n"
							"is numeric but is not a valid index. Use the\n"
							"List command to get a list of spaces.\n"
							)
						.arg( id )
						);
			}
		}
		*space = new_val;
		return true;
	}
	*space = NULL;
	return false;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
PgSpace *					CmdArgs::getNamedSpace		(
		BBlocks::UserMsg & um, CpgDoc * doc, bool b_use_crt )
{
	Q_ASSERT( doc != NULL );
	PgSpace *	new_val = NULL;
	QString		s_arg;
	bool		b;

	/* named argument to indicate the document */
	if ( extractNamed( "SPC", s_arg ) )
	{
		int id = s_arg.toInt( &b );
		if ( ( id < 0 ) || ( b == false ) )
		{
			new_val = doc->spaceByName( s_arg );
			if ( new_val == NULL )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The space name that was provided:\n"
							"%1\n"
							"was not found inside document [%2] - %3.\n"
							)
						.arg( s_arg )
						.arg( doc->id() )
						.arg( doc->documentName() )
						);
				return NULL;
			}
		}
		else
		{
			new_val = doc->space( id );
			if ( new_val == NULL )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The argument that was provided - %1\n"
							"is numeric but is not a valid index. Use the\n"
							"List command to get a list of spaces.\n"
							)
						.arg( id )
						);
				return NULL;
			}
		}
	}
	else if ( b_use_crt )
	{
		new_val = doc->currentSpace();
		if ( new_val == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"There is no active space\n"
						"inside document [%1] - %2.\n" )
					.arg( doc->id() )
					.arg( doc->documentName() )
					);
			return NULL;
		}
	}
	return new_val;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
CpgDoc *					CmdArgs::getDocument		( BBlocks::UserMsg & um )
{
	if ( argumentsCount() == 0 )
	{
		um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
					"Either numeric or textual argument expected to identify the document.\n"
					)
				);
		return NULL;
	}

	bool b = false;
	CpgDoc * new_val;
	QString	s_arg = extractArg( 0 );
	int id = s_arg.toInt( &b );
	if ( ( id < 0 ) || ( b == false ) )
	{
		s_arg = QDir().absoluteFilePath( s_arg );
		new_val = CpgLibrary::docByFile( s_arg );
		if ( new_val == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The file that was provided:\n"
						"%1\n"
						"was not found to be associated with any document.\n"
						"Use the List command to get a list of valid id's.\n"
						)
					.arg( s_arg )
					);
			return NULL;
		}
	}
	else
	{
		new_val = CpgLibrary::docById( id );
		if ( new_val == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The argument that was provided - %1\n"
						"is numeric but is not a valid id. Use the\n"
						"List command to get a list of valid id's.\n"
						)
					.arg( id )
					);
			return NULL;
		}
	}
	return new_val;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
IDrawFile *				CmdArgs::getFileFormat	( BBlocks::UserMsg & um )
{

	if ( argumentsCount() == 0 )
	{
		um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
					"Either numeric or textual argument\n"
					"expected to identify the file format.\n"
					)
				);
		return NULL;
	}

	/* get the argument and attempt to convert it to an integer */
	IDrawFile *	new_def;
	bool		b;
	QString		s_arg = extractArg( 0 );
	int			id = s_arg.toInt( &b );
	if ( ( id < 0 ) || ( b == false ) )
	{ /* invalid integer */
		new_def = FormatManager::instFromName( s_arg );
		if ( new_def == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The name that was provided:\n"
						"%1\n"
						"was not found to be associated with any file format.\n"
						"Use the FileFormats command to get a list of valid names.\n"
						)
					.arg( s_arg )
					);
			return NULL;
		}
	}
	else
	{
		new_def = FormatManager::item( id );
		if ( new_def == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The id that was provided - %1\n"
						"was not found to be associated with any file format.\n"
						"Use the FileFormats command to get a list of valid indices.\n"
						)
					.arg( id )
					);
			return NULL;
		}
	}
	return new_def;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
PlugIn *	CmdArgs::getPlugIn		(
		QString & s_file, BBlocks::UserMsg & um, bool b_plg_req )
{
	s_file.clear();
	if ( argumentsCount() == 0 )
	{
		um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
					"Either numeric or textual argument\n"
					"expected to identify the plug-in.\n"
					)
				);
		return NULL;
	}

	PlugIn *	ret_p = NULL;
	bool				b;
	QString				s_arg = extractArg( 0 );
	int					id = s_arg.toInt( &b );

	if ( ( id < 0 ) || ( b == false ) )
	{ /* invalid integer */
		ret_p = PlgInMan::byFile( s_file );
		if ( ret_p != NULL )
		{
			s_file = ret_p->file();
		}
		else
		{
			s_file = QDir().absoluteFilePath( s_arg );
			if ( b_plg_req )
			{
				um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
							"The file that was provided:\n"
							"%1\n"
							"was not found to be associated with any plug-ins.\n"
							"Use the PIn.List command to get a list of valid names.\n"
							)
						.arg( s_arg )
						);
				return NULL;
			}
		}
	}
	else
	{ /* valid integer - index in the list */
		ret_p = PlgInMan::plugin( id );
		if ( ret_p == NULL )
		{
			um.add( BBlocks::UserMsgMgr::MSG_ERROR, QObject::tr(
						"The id that was provided - %1\n"
						"was not found to be associated with any plug-in.\n"
						"Use the PIn.List command to get a list of valid indices.\n"
						)
					.arg( id )
					);
			return NULL;
		}
		s_file = ret_p->file();
	}

	return ret_p;
}
/* ========================================================================= */

/*  CLASS    =============================================================== */
//
//
//
//
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
